package ca.venasse.pinventory.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.orm.jpa.JpaDialect;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.aspectj.AnnotationTransactionAspect;

import ca.venasse.org.springframework.context.support.ConfigurationSupport;

@Configuration
@ImportResource("/context-data.xml")
public class DatabaseConfiguration {

	@Bean
	public AnnotationTransactionAspect annotationTransactionAspect(
			PlatformTransactionManager transactionManager) {
		AnnotationTransactionAspect aspect = AnnotationTransactionAspect.aspectOf();
		aspect.setTransactionManager(transactionManager);
		return aspect;
	}

	@Bean
	public DataSource dataSource(ConfigurationSupport configurationSupport) {
		JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
		bean.setJndiName("java:comp/env/jdbc/inventory");
		return (DataSource) configurationSupport.getObject(bean);
	}

	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		return new DefaultAdvisorAutoProxyCreator();
	}

	@Bean
	public EntityManagerFactory entityManagerFactory(DataSource dataSource,
			ConfigurationSupport configurationSupport, JpaDialect jpaDialect) {
		LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
		entityManagerFactory.setPersistenceUnitName("inventory");
		entityManagerFactory.setDataSource(dataSource);
		entityManagerFactory.setJpaDialect(jpaDialect);
		return configurationSupport.getObject(entityManagerFactory);
	}

	@Bean
	public JpaDialect jpaDialect() {
		return new HibernateJpaDialect();
	}

	@Bean
	public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
		return new PersistenceAnnotationBeanPostProcessor();
	}

	@Bean
	public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactory);
		return transactionManager;
	}

}
